package com.lancoo.rxretrofitlibrary.http;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.lancoo.reviewsystem.utils.TimeUtils;
import com.lancoo.rxretrofitlibrary.Api.BaseApi;
import com.lancoo.rxretrofitlibrary.LoggingInterceptor;
import com.lancoo.rxretrofitlibrary.RxRetrofitApp;
import com.lancoo.rxretrofitlibrary.exception.RetryWithDelay;
import com.lancoo.rxretrofitlibrary.listener.HttpOnNextListener;
import com.lancoo.rxretrofitlibrary.subscribers.ProgressSubscriber;
import com.orhanobut.logger.Logger;
import com.trello.rxlifecycle.android.ActivityEvent;
import com.trello.rxlifecycle.android.FragmentEvent;

import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

import static com.lancoo.rxretrofitlibrary.http.RetrofitUrlManager.API_DOMAIN_NAME;

/**
 * http交互处理类
 * Created by tangminglong on 17/5/11.
 */

public class HttpManager {


    private volatile static HttpManager INSTANCE;

    //构造方法私有
    private HttpManager() {
    }

    //获取单例
    public static HttpManager getInstance() {
        if (INSTANCE == null) {
            synchronized (HttpManager.class) {
                if (INSTANCE == null) {
                    INSTANCE = new HttpManager();
                }
            }
        }
        return INSTANCE;
    }

    /**
     * 处理http请求
     *
     * @param basePar 封装的请求数据
     *
     */
    public void doHttpDeal(BaseApi basePar) {
        doHttpDeal(basePar,null);
    }

    /**
     * 一般用在一个页面访问下一个接口但是需要取消上一个接口请求的需求 eg.带下拉菜单的选择
     * @param basePar 封装的请求数据
     * @param progressSubscriber subscriber暴露外面自己处理
     */
    public void doHttpDeal(BaseApi basePar, ProgressSubscriber progressSubscriber) {
        ProgressSubscriber subscriber;
        //手动创建一个OkHttpClient并设置超时时间缓存等设置
        OkHttpClient.Builder builder = RetrofitUrlManager.getInstance().with(new OkHttpClient.Builder());
        builder.connectTimeout(basePar.getConnectionTime(), TimeUnit.SECONDS);
        //缓存
       // builder.addInterceptor(new CookieInterceptor(basePar.isCache(), basePar.getUrl()));
        builder.addInterceptor(new LoggingInterceptor());
        if(RxRetrofitApp.isDebug()){
            builder.addInterceptor(getHttpLoggingInterceptor());
        }


        Gson gson = new GsonBuilder()//设置服务器返回的时间格式
                .setDateFormat(TimeUtils.SERVER_DATE_FORM)
                .create();

        /*创建retrofit对象*/
        Retrofit.Builder retrofitBuilder = new Retrofit.Builder()
                .client(builder.build())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .baseUrl(RetrofitUrlManager.getInstance().fetchDomainStr(API_DOMAIN_NAME))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create());


        Retrofit retrofit = retrofitBuilder.build();

        /*rx处理*/
        if (progressSubscriber != null){
            subscriber = progressSubscriber;
        }else {
            subscriber = new ProgressSubscriber(basePar);
        }
        Observable observable = basePar.getObservable(retrofit)
                .retryWhen(new RetryWithDelay(basePar.getRetryCount(),basePar.getRetryDelay(),
                        basePar.getRetryIncreaseDelay()))
                /*.flatMap(new TokeanFunc(basePar,retrofit))*/
                 /*失败后的retry配置*/
                //.retryWhen(new RetryWhenNetworkException())
                /*生命周期管理*/
//                .compose(basePar.getRxAppCompatActivity().bindToLifecycle())
                .compose(basePar.isActivity() ?
                        basePar.getRxAppCompatActivity().bindUntilEvent(ActivityEvent.DESTROY) :
                        basePar.getRxFragment().bindUntilEvent(FragmentEvent.DESTROY))
                /*http请求线程*/
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                /*回调线程*/
                .observeOn(AndroidSchedulers.mainThread())
                /*结果判断*/
                ;


        /*链接式对象返回*/
      /*  SoftReference<HttpOnNextListener> httpOnNextListener = basePar.getListener();
        if (httpOnNextListener != null && httpOnNextListener.get() != null) {
            httpOnNextListener.get().onNext(observable);
        }*/

        /*数据回调*/
        observable.subscribe(subscriber);

    }

    /**
     * 处理xml请求方式
     * @param basePar 封装的请求数据
     */
    public void doHttpXmlDeal(BaseApi basePar) {
        //手动创建一个OkHttpClient并设置超时时间缓存等设置
        OkHttpClient.Builder builder = RetrofitUrlManager.getInstance().with(new OkHttpClient.Builder());
        builder.connectTimeout(basePar.getConnectionTime(), TimeUnit.SECONDS);
        //缓存设置
        // builder.addInterceptor(new CookieInterceptor(basePar.isCache(), basePar.getUrl()));
        builder.addInterceptor(new LoggingInterceptor());
        if(RxRetrofitApp.isDebug()){
            builder.addInterceptor(getHttpLoggingInterceptor());
        }


        /*创建retrofit对象*/
        Retrofit retrofit = new Retrofit.Builder()
                .client(builder.build())
                .addConverterFactory(SimpleXmlConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .baseUrl(RetrofitUrlManager.getInstance().fetchDomainStr(API_DOMAIN_NAME))
                .build();


        /*rx处理*/
        ProgressSubscriber subscriber = new ProgressSubscriber(basePar);
        Observable observable = basePar.getObservable(retrofit)
                .compose(basePar.isActivity() ?
                        basePar.getRxAppCompatActivity().bindUntilEvent(ActivityEvent.DESTROY) :
                        basePar.getRxFragment().bindUntilEvent(FragmentEvent.DESTROY))
                /*http请求线程*/
                .retryWhen(new RetryWithDelay(basePar.getRetryCount(),basePar.getRetryDelay(),
                        basePar.getRetryIncreaseDelay()))
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                /*回调线程*/
                .observeOn(AndroidSchedulers.mainThread());
                /*结果判断*/



        /*链接式对象返回*/
        HttpOnNextListener httpOnNextListener = basePar.getListener();
        if (httpOnNextListener != null) {
            httpOnNextListener.onNext(observable);
        }

        /*数据回调*/
        observable.subscribe(subscriber);

    }


    /**
     * 日志输出
     * 自行判定是否添加
     * @return
     */
    protected HttpLoggingInterceptor getHttpLoggingInterceptor(){
        //日志显示级别
        HttpLoggingInterceptor.Level level= HttpLoggingInterceptor.Level.BODY;
        //新建log拦截器
        HttpLoggingInterceptor loggingInterceptor=new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                if (TextUtils.isEmpty(message)) return;
                if (message.startsWith("{") || message.startsWith("[")) {
                    Logger.d("收到响应: " + message);
                    Logger.json(message);
                }
            }
        });
        loggingInterceptor.setLevel(level);
        return loggingInterceptor;
    }


}
